import { Inject, Injectable, forwardRef } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { BusinessException } from 'src/common/exceptions/business.exception'
import { Budget } from 'src/entity/Budget'
import { Purchase } from 'src/entity/Purchase'
import { Task } from 'src/entity/Task'
import { TaskService } from 'src/task/task.service'
import { Connection, IsNull, Not, Repository } from 'typeorm'
import { isNull } from 'util'
import { v4 as uuidV4 } from 'uuid'

@Injectable()
export class PurchaseService {
  constructor(
    @InjectRepository(Purchase)
    private purchaseRepository: Repository<Purchase>,
    @Inject(forwardRef(() => TaskService))
    private readonly taskService: TaskService,
    private connection: Connection,
  ) { }

  async add(data) {
    const purchaseCode = 'P' + uuidV4()
    data.purchaseCode = purchaseCode
    data.purchaseStatus = '0'

    await this.connection.transaction(async (manager) => {
      const budgetSqlData = await manager.findOne(Budget, {
        where: {
          id: data.budgetId,
        },
      })
      if (data.purchaseAmount > budgetSqlData.budgetAmount) {
        throw new BusinessException('采购金额不能大于预算金额')
      }
      const sqlData = await this.purchaseRepository.save(data)
      const taskData = new Task()
      taskData.receiveBranch = sqlData.purchaseBranch
      taskData.receiveBranchId = sqlData.purchaseBranchId
      taskData.receivePerson = sqlData.purchasePerson
      taskData.receivePersonId = sqlData.purchasePersonId
      taskData.receiveCode = sqlData.purchaseCode
      taskData.receiveDate = sqlData.purchaseDate
      taskData.taskName = sqlData.purchaseName
      taskData.taskStatus = sqlData.purchaseStatus
      taskData.taskType = '1'
      await this.taskService.add(taskData)
    })

    return data
  }

  async del(id: number) {
    let data
    await this.connection.transaction(async (manager) => {
      const sqlData = await this.purchaseRepository.findOne({
        where: {
          id,
        },
      })
      await this.taskService.delByCode(sqlData.purchaseCode)
      data = await manager.update(
        Purchase,
        {
          id: id,
        },
        {
          isDelete: true,
        },
      )
    })
    return data
  }

  async update(data) {
    data.purchaseStatus = '0'
    data.reason = null
    let sqlData
    await this.connection.transaction(async (manager) => {
      await this.taskService.updateProperty(
        data.purchaseCode,
        'taskStatus',
        data.purchaseStatus,
      )
      await this.taskService.updateProperty(data.purchaseCode, 'reason', null)
      await this.taskService.updateProperty(data.purchaseCode, 'taskDate', null)
      await this.taskService.updateProperty(
        data.purchaseCode,
        'taskPersonId',
        null,
      )
      await this.taskService.updateProperty(
        data.purchaseCode,
        'taskPerson',
        null,
      )
      sqlData = await this.purchaseRepository.update(
        {
          id: data.id,
        },
        data,
      )
    })
    return sqlData
  }

  // 更新某个属性
  async updateProperty(code, property, value) {
    return await this.purchaseRepository.update(
      {
        purchaseCode: code,
      },
      {
        [property]: value,
      },
    )
  }

  // 分页查询
  async getPageList({
    pageRequest: { pageIndex, pageSize },
    purchaseCode,
    purchaseName,
    purchasePerson,
    purchaseBranch,
    budgetId,
    purchaseStatus,
    orgId,
  }) {
    const sqlAllData = await this.purchaseRepository.find({
      where: {
        isDelete: IsNull(),
        purchaseBranchId: orgId,
        purchaseCode: purchaseCode,
        purchaseName: purchaseName,
        purchasePerson: purchasePerson,
        purchaseBranch: purchaseBranch,
        budgetId: budgetId ? parseInt(budgetId) : undefined,
        purchaseStatus: purchaseStatus,
      },
    })

    const sqlData = await this.purchaseRepository.find({
      where: {
        isDelete: IsNull(),
        purchaseBranchId: orgId,
        purchaseCode: purchaseCode,
        purchaseName: purchaseName,
        purchasePerson: purchasePerson,
        purchaseBranch: purchaseBranch,
        budgetId: budgetId ? parseInt(budgetId) : undefined,
        purchaseStatus: purchaseStatus,
      },
      skip: (pageIndex - 1) * pageSize,
      take: pageSize,
      withDeleted: false,
    })

    return {
      content: sqlData.map((item) => {
        return {
          ...item,
          purchaseTypeId: item.purchaseTypeId.toString(),
          budgetId: item.budgetId.toString(),
        }
      }),
      total: sqlAllData.length,
    }
  }

  // 获取采购详情 purchaseCode -> *
  async getDetailByCode(code) {
    const sqlData = await this.purchaseRepository.findOne({
      where: {
        purchaseCode: code,
        isDelete: IsNull(),
      },
    })
    return {
      ...sqlData,
      purchaseTypeId: sqlData.purchaseTypeId.toString(),
      budgetId: sqlData.budgetId.toString(),
    }
  }

  // 获取采购列表
  async getPurchaseList(isInStore = false, orgId: number) {
    const sqlDataList = await this.purchaseRepository.find({
      where: isInStore
        ? {
          isDelete: IsNull(),
          purchaseStatus: '2',
          purchaseBranchId: orgId,
          isInStore: IsNull(),
        }
        : {
          isDelete: IsNull(),
          purchaseBranchId: orgId,
          purchaseStatus: '2',
        },
    })
    return sqlDataList.map((item) => {
      return {
        label: item.purchaseName,
        value: item.id.toString(),
      }
    })
  }

  // 获取采购详情
  async getPurchaseDetail(id) {
    return await this.purchaseRepository.findOne({
      where: {
        isDelete: IsNull(),
        purchaseStatus: '2',
        id,
      },
    })
  }
}
